﻿Imports System
Imports System.Collections.Generic

Namespace System.Workflow.ComponentModel
    Friend NotInheritable Class PathParser
        ' Methods
        Private Sub AddIndexer()
            Dim index As Integer = Me.index
            Dim num2 As Integer = 1
            Do While (num2 > 0)
                If (Me.index >= Me.pathLength) Then
                    Return
                End If
                If (Me.pathValue.Chars(Me.index) = "["c) Then
                    num2 += 1
                ElseIf (Me.pathValue.Chars(Me.index) = "]"c) Then
                    num2 -= 1
                End If
                Me.index += 1
            Loop
            Dim n As String = Me.pathValue.Substring(index, ((Me.index - index) - 1)).Trim
            Dim item As New SourceValueInfo(SourceValueType.Indexer, Me.drillIn, n)
            Me.al.Add(item)
            Me.StartNewLevel
        End Sub

        Private Sub AddProperty()
            Dim index As Integer = Me.index
            Do While ((Me.index < Me.pathLength) AndAlso (PathParser.SpecialChars.IndexOf(Me.pathValue.Chars(Me.index)) < 0))
                Me.index += 1
            Loop
            Dim n As String = Me.pathValue.Substring(index, (Me.index - index)).Trim
            Dim item As New SourceValueInfo(SourceValueType.Property, Me.drillIn, n)
            Me.al.Add(item)
            Me.StartNewLevel
        End Sub

        Friend Function Parse(ByVal path As String, ByVal returnResultBeforeError As Boolean) As List([Of] SourceValueInfo)
            Me.pathValue = If((Not path Is Nothing), path.Trim, String.Empty)
            Me.pathLength = Me.pathValue.Length
            Me.index = 0
            Me.drillIn = DrillIn.IfNeeded
            Me.al.Clear
            Me.error = Nothing
            Me.state = State.Init
            If ((Me.pathLength > 0) AndAlso (Me.pathValue.Chars(0) = "."c)) Then
                Dim item As New SourceValueInfo(SourceValueType.Property, Me.drillIn, String.Empty)
                Me.al.Add(item)
            End If
            Do While (Me.state <> State.Done)
                Dim flag As Boolean
                Dim ch As Char = If((Me.index < Me.pathLength), Me.pathValue.Chars(Me.index), ChrW(0))
                Select Case Me.state
                    Case State.Init
                        Select Case ch
                            Case "\"c
                                goto Label_015C
                            Case "]"c
                                goto Label_010C
                        End Select
                        goto Label_015C
                    Case State.Prop
                        flag = False
                        Select Case ch
                            Case ChrW(0)
                                goto Label_018C
                            Case "."c
                                goto Label_017F
                            Case "["c
                                goto Label_0188
                        End Select
                        goto Label_019C
                    Case Else
                        [Continue]
                End Select
                Me.state = State.Prop
                [Continue] Do
            Label_010C:
                Me.error = String.Concat(New Object() { "path[", Me.index, "] = ", ch })
                If Not returnResultBeforeError Then
                    Return PathParser.EmptyInfo
                End If
                Return Me.al
            Label_015C:
                Me.AddProperty
                [Continue] Do
            Label_017F:
                Me.drillIn = DrillIn.Never
                goto Label_01EC
            Label_0188:
                flag = True
                goto Label_01EC
            Label_018C:
                Me.index -= 1
                goto Label_01EC
            Label_019C:
                Me.error = String.Concat(New Object() { "path[", Me.index, "] = ", ch })
                If Not returnResultBeforeError Then
                    Return PathParser.EmptyInfo
                End If
                Return Me.al
            Label_01EC:
                Me.index += 1
                If flag Then
                    Me.AddIndexer
                Else
                    Me.AddProperty
                End If
            Loop
            If ((Not Me.error Is Nothing) AndAlso Not returnResultBeforeError) Then
                Return PathParser.EmptyInfo
            End If
            Return Me.al
        End Function

        Private Sub StartNewLevel()
            If (Me.index >= Me.pathLength) Then
                Me.state = State.Done
            End If
            Me.drillIn = DrillIn.Never
        End Sub


        ' Properties
        Friend ReadOnly Property [Error] As String
            Get
                Return Me.error
            End Get
        End Property


        ' Fields
        Private al As List([Of] SourceValueInfo) = New List([Of] SourceValueInfo)
        Private drillIn As DrillIn
        Private Shared EmptyInfo As List([Of] SourceValueInfo) = New List([Of] SourceValueInfo)(1)
        Private [error] As String = String.Empty
        Private index As Integer
        Private Const NullChar As Char = ChrW(0)
        Private pathLength As Integer
        Private pathValue As String
        Private Shared SpecialChars As String = ".[]"
        Private state As State

        ' Nested Types
        Private Enum State
            ' Fields
            Done = 2
            Init = 0
            Prop = 1
        End Enum
    End Class
End Namespace

